/**
 * @description 时间戳获取年月日时分秒
 * @author lijiaxi
 * @export fn
 * @param {*} time 可转为时间对象的参数
 * @param {*} [format='-'] 时间格式连接符
 * @returns String
 */
export function parseTime(time, format = '-,:') {
    if (!time) {
      return '-'
    } 
    time = time.toString().length === 13 ? time : time * 1000
    let sep = format.split(',')
    return `${getYMD(time, sep[0])} ${getHMS(time, sep[1])}`
}
/**
 * @description 时间戳获取年月日
 * @author lijiaxi
 * @export fn
 * @param {*} o 可转为时间对象的参数
 * @param {string} [format='-'] 时间格式连接符
 * @returns String
 */
export function getYMD(o, format = '-') {
  o = o.toString().length === 13 ? o : o * 1000
  let date = new Date(o),
  Y = date.getFullYear(),
  M = date.getMonth() + 1 ,
  D = date.getDate() + ' ';
  M = M < 10 ? '0' + M : M
  D = D < 10 ? '0' + D : D
  return [Y, M, D].join(format)
}
/**
 * @description 获取时分秒
 * @author lijiaxi
 * @export fn
 * @param {*} o 可转为时间对象的参数
 * @param {string} [format=':'] 时间格式连接符
 * @returns String
 */
export function getHMS(o, format = ':') {
  o = o.toString().length === 13 ? o : o * 1000
  let date = new Date(o),
  h = date.getHours(),
  m = date.getMinutes(),
  s = date.getSeconds();
  h = h < 10 ? '0' + h : h
  m = m < 10 ? '0' + m : m
  s = s < 10 ? '0' + s : s
  return [h, m, s].join(format)
}

/**
 * @description 获取时分
 * @author lijiaxi
 * @export fn
 * @param {*} o 可转为时间对象的参数
 * @param {string} [format=':'] 时间格式连接符
 * @returns String
 */
export function getHM(o, format = ':') {
  o = o.toString().length === 13 ? o : o * 1000
  let date = new Date(o),
  h = date.getHours(),
  m = date.getMinutes();
  h = h < 10 ? '0' + h : h
  m = m < 10 ? '0' + m : m
  return [h, m].join(format)
}

/**
 * @description 把时间转换成已使用的时间
 * @author lijiaxi
 * @export fn
 * @param {*} startTime 开始时间
 * @param {*} endTime 结束时间
 * @returns object | String
 */
export function getdTimes (startTime, endTime) {
  if (startTime > endTime) {
    return '1分钟'
  }
  let argsLen = arguments.length
  if (argsLen == 2) {
    var val = (endTime - startTime) / 1000;
  } else {
    var val = startTime / 1000;
  }
  let d = Math.floor(val / 86400);
      val = val % 86400
  let h = Math.floor( val / 3600); 
      h = h < 10 ? '0' + h : '' + h
      val = val % 3600
  let m = Math.floor(val / 60);
      m = m < 10 ? '0' + m : '' + m
  let s = Math.floor(val % 60);
      s = s < 10 ? '0' + s : '' + s
  return { d, h, m, s }
}

export function getdTime (startTime, endTime) {
  if (startTime > endTime) {
    return '1分钟'
  }
  let argsLen = arguments.length
  if (argsLen == 2) {
    var val = (endTime - startTime) / 1000;
  } else {
    var val = startTime / 1000;
  }
  let d = Math.floor(val / 86400);
      val = val % 86400
  let h = Math.floor( val / 3600); 
      val = val % 3600
  let m = Math.floor(val / 60);
  let s = Math.floor(val % 60);
  d = {
    k: d,
    v: d + '天'
  }
  h = {
    k: h,
    v: h + '小时'
  }
  m = {
    k: m,
    v: m + '分钟'
  }
  s = {
    k: s,
    v: s + '秒'
  }
  return [d, h, m, s].filter(item => item.k).map(item => item.v).join('')
}

/**
 * @description 格式化url参数,小程序跳转
 * @author lijiaxi
 * @export fn
 * @param {*} [{url = '', ...other}={}] url为页面路径，other为其他参数
 * @returns String | Object
 */
export function queryStringify ({url = '', ...other} = {}) {
  let res = []
  for (let key in other) {
    let value = typeof value === 'object' ? 
        JSON.stringify(other[key]) : 
        other[key]
    res.push(`${key}=${value}`)
  }
  res = res.join('&')
  res = url ? 
  `${url}?${res}` : 
    res
  return res
}
/**
 * @description 截取url参数
 * @author lijiaxi
 * @export fn
 * @param {string} [url='']
 * @returns Object
 */
export function urlParse (url = '') {
  url = url.split('?')[1] ? url.split('?')[1] : url
  let res = {}
  let kv = url.split('&')
  for (let i = 0;i < kv.length; i++) {
    let qs = kv[i].split('=')
    res[decodeURIComponent(qs[0])] = decodeURIComponent(qs[1])
  }
  return res
}

/**
 * 将科学计数法的数字转为字符串
 * 说明：运算精度丢失方法中处理数字的时候，如果出现科学计数法，就会导致结果出错  
 * 4.496794759834739e-9  ==> 0.000000004496794759834739
 * 4.496794759834739e+9  ==> 4496794759.834739
 * @param  num 
*/

export function toNonExponential  (num) {
  if(num == null) {
      return num;
  }
  if(typeof num == "number") {
      var m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
      return num.toFixed(Math.max(0, (m[1] || '').length - m[2]));
  }else {
      return num;
  }
}

 
/**
 * 乘法 - js运算精度丢失问题
 * @param arg1  数1
 * @param arg2  数2
 * 0.0023 * 100 ==> 0.22999999999999998
 * {{ 0.0023 | multiply(100) }} ==> 0.23
 */

export function floatMultiply  (arg1, arg2){
  arg1 = Number(arg1);
  arg2 = Number(arg2);
  if ((!arg1 && arg1!==0) || (!arg2 && arg2!==0)) {
      return null;
  }
  arg1 = toNonExponential(arg1);
  arg2 = toNonExponential(arg2);
  var n1, n2;
  var r1, r2; // 小数位数
  try {
      r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
      r1 = 0;
  }
  try {
      r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
      r2 = 0;
  }
  n1 = Number(arg1.toString().replace(".", ""));
  n2 = Number(arg2.toString().replace(".", ""));
  return n1 * n2 / Math.pow(10, r1 + r2);
}

/**
 * 除法 - js运算精度丢失问题
 * @param arg1  数1
 * @param arg2  数2
 * 0.0023 / 0.00001 ==> 229.99999999999997
 * {{ 0.0023 | divide(0.00001) }} ==> 230
 */

export function floatDivide  (arg1, arg2)  {
  arg1 = Number(arg1);
  arg2 = Number(arg2);
  if (!arg2) {
      return null;
  }
  if (!arg1 && arg1!==0) {
      return null;
  }else if(arg1===0) {
      return 0;
  }
  arg1 = toNonExponential(arg1);
  arg2 = toNonExponential(arg2);
  var n1, n2;
  var r1, r2; // 小数位数
  try {
      r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
      r1 = 0;
  }
  try {
      r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
      r2 = 0;
  }
  n1 = Number(arg1.toString().replace(".", ""));
  n2 = Number(arg2.toString().replace(".", ""));
  return floatMultiply((n1 / n2), Math.pow(10, r2 - r1));
  // return (n1 / n2) * Math.pow(10, r2 - r1);   // 直接乘法还是会出现精度问题
}

/**
 * 加法 - js运算精度丢失问题
 * @param arg1  数1
 * @param arg2  数2
 * 0.0023 + 0.00000000000001 ==> 0.0023000000000099998
 * {{ 0.0023 | plus(0.00000000000001) }} ==> 0.00230000000001
 */
export function  floatAdd (arg1, arg2)  {
  arg1 = Number(arg1) || 0;
  arg2 = Number(arg2) || 0;
  arg1 = toNonExponential(arg1);
  arg2 = toNonExponential(arg2);
  var r1, r2, m;
  try {
      r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
      r1 = 0;
  }
  try {
      r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
      r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  return (floatMultiply(arg1, m) + floatMultiply(arg2, m)) / m;
}

/**
* 减法 - js运算精度丢失问题
* @param arg1  数1
* @param arg2  数2
* 0.0023 - 0.00000011  ==>  0.0022998899999999997
* {{ 0.0023 | minus( 0.00000011 ) }}  ==>  0.00229989
*/
export function   floatSub  (arg1, arg2) {
  arg1 = Number(arg1) || 0;
  arg2 = Number(arg2) || 0;
  arg1 = toNonExponential(arg1);
  arg2 = toNonExponential(arg2);
  var r1, r2, m, n;
  try {
      r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
      r1 = 0;
  }
  try {
      r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
      r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  // 动态控制精度长度
  n = (r1 >= r2) ? r1 : r2;
  return ((floatMultiply(arg1, m) - floatMultiply(arg2, m)) / m).toFixed(n);
}


/**
* 取余 - js运算精度丢失问题
* @param arg1  数1
* @param arg2  数2
* 12.24 % 12  ==> 0.2400000000000002
* {{ 12.24 | mod( -12 ) }}  ==>  0.24
*/
export function floatMod  (arg1, arg2) {
  arg1 = Number(arg1);
  arg2 = Number(arg2);
  if (!arg2) {
      return null;
  }
  if (!arg1 && arg1!==0) {
      return null;
  }else if(arg1===0) {
      return 0;
  }
  let intNum = arg1 / arg2;
  intNum = intNum < 0 ? Math.ceil( arg1 / arg2 ) : Math.floor( arg1 / arg2 );  // -1.02 取整为 -1; 1.02取整为1
  let intVal = floatMultiply(intNum, arg2);
  return floatSub( arg1,intVal );  12.4
}
